package com.fzy.common.date;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

/**
 * 日期工具类
 *
 * @author 冯赵杨
 * @create 2018/7/20
 */
public class DateUtil {

    private DateUtil() {
    }

    /**
     * 定义常量
     **/
    public static final String DATE_JFP_STR = "yyyyMM";
    public static final String DATE_FULL_STR = "yyyy-MM-dd HH:mm:ss";
    public static final String DATE_SMALL_STR = "yyyy-MM-dd";
    public static final String DATE_KEY_STR = "yyMMddHHmmss";
    public static final String DATE_ALL_STR = "yyyyMMddHHmmssSSS";

    public static SimpleDateFormat getMonthFormat() {
        return new SimpleDateFormat("yyyy-MM");
    }

    public static SimpleDateFormat getDayFormat() {
        return new SimpleDateFormat("yyyyMMdd");
    }

    public static SimpleDateFormat getSimpleFormat() {
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    }

    public static SimpleDateFormat getCustomFormat(String pattern) {
        return new SimpleDateFormat(pattern);
    }

    public static SimpleDateFormat getDayHourFormat() {
        return new SimpleDateFormat("yyyyMMddHH");
    }

    public static SimpleDateFormat getALLFormat() {
        return new SimpleDateFormat(DATE_ALL_STR);
    }


    /**
     * 使用预设格式提取字符串日期
     *
     * @param strDate 日期字符串
     * @return
     * @author 冯赵杨
     * @date 2017年6月23日 上午10:38:13
     */
    public static Date parse(String strDate) {
        return parse(strDate, DATE_FULL_STR);
    }

    /**
     * 使用用户格式提取字符串日期
     *
     * @param strDate 日期字符串
     * @param pattern 日期格式
     * @return
     * @author 冯赵杨
     * @date 2017年6月23日 上午10:38:13
     */
    public static Date parse(String strDate, String pattern) {
        SimpleDateFormat df = new SimpleDateFormat(pattern);
        try {
            return df.parse(strDate);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 与当前时间比较
     *
     * @param date1
     * @return
     * @author 冯赵杨
     * @date 2017年6月23日 上午10:38:13
     */
    public static int compareDateWithNow(Date date1) {
        Date date2 = new Date();
        return date1.compareTo(date2);
    }

    /**
     * 两个时间比较
     *
     * @param date1
     * @param date2
     * @return
     * @author 冯赵杨
     * @date 2017年6月23日 上午10:38:13
     */
    public static int compareDate(Date date1, Date date2) {
        Calendar c1 = Calendar.getInstance();
        c1.setTime(date1);
        Calendar c2 = Calendar.getInstance();
        c2.setTime(date2);

        return c1.get(Calendar.MONTH) - c2.get(Calendar.MONTH);
    }

    /**
     * 两个时间比较(时间戳比较)
     *
     * @param date1
     * @return
     * @author 冯赵杨
     * @date 2017年6月23日 上午10:38:13
     */
    public static int compareDateWithNow(long date1) {
        long date2 = System.currentTimeMillis();

        return Long.compare(date1, date2);
    }

    /**
     * 获取系统当前时间
     *
     * @return
     * @author 冯赵杨
     * @date 2017年6月23日 上午10:38:13
     */
    public static String getNowTime() {
        SimpleDateFormat df = new SimpleDateFormat(DATE_FULL_STR);
        return df.format(new Date());
    }

    /**
     * 获取系统当前时间 返回Date类型
     *
     * @author 冯赵杨
     * @date 2017年6月23日 上午10:38:13
     */
    public static Date getNowDate(String pattern) {
        SimpleDateFormat df = new SimpleDateFormat(pattern);
        String dateStr = df.format(new Date());
        return parse(dateStr, pattern);
    }

    /**
     * Date格式转String
     *
     * @author 冯赵杨
     * @date 2016年11月16日 下午5:14:42
     */
    public static String date2String(Date date) {
        SimpleDateFormat df = new SimpleDateFormat(DATE_FULL_STR);
        return df.format(date);
    }

    /**
     * Timestamp格式转String
     *
     * @author 冯赵杨
     * @date 2016年11月16日 下午5:14:42
     */
    public static String date2String(Timestamp date) {
        SimpleDateFormat df = new SimpleDateFormat(DATE_FULL_STR);
        return df.format(date);
    }

    /**
     * 日期转换成字符串 根据日期表达式
     *
     * @param pattern yyyy-MM-dd / yyyy-MM-dd HH:mm:ss
     * @author 冯赵杨
     * @date 2016年11月16日 下午5:14:42
     */
    public static String date2String(Date date, String pattern) {
        SimpleDateFormat df = new SimpleDateFormat(pattern);
        return df.format(date);
    }

    public static String getYYYYMMDD(Date date) {
        SimpleDateFormat df = new SimpleDateFormat(DATE_SMALL_STR);
        return df.format(date);
    }

    /**
     * 日期转换成字符串
     *
     * @author 冯赵杨
     * @date 2016年11月16日 下午5:15:00
     */
    public static String date2String(Object date) {
        SimpleDateFormat df = new SimpleDateFormat(DATE_FULL_STR);
        return df.format(date);
    }

    /**
     * @param pattern yyyy-MM-dd / yyyy-MM-dd HH:mm:ss
     * @desc
     * @author 冯赵杨
     * @date 2016年11月16日 下午5:14:42
     */
    public static String date2String(Object date, String pattern) {
        SimpleDateFormat df = new SimpleDateFormat(pattern);
        return df.format(date);
    }

    /**
     * 获取系统当前时间
     *
     * @param pattern
     * @return
     * @author 冯赵杨
     * @date 2017年6月23日 上午10:38:13
     */
    public static String getNowTime(String pattern) {
        SimpleDateFormat df = new SimpleDateFormat(pattern);
        return df.format(new Date());
    }

    /**
     * 获取系统当前计费期
     *
     * @return
     * @author 冯赵杨
     * @date 2017年6月23日 上午10:38:13
     */
    public static String getJFPTime() {
        SimpleDateFormat df = new SimpleDateFormat(DATE_JFP_STR);
        return df.format(new Date());
    }

    /**
     * 将指定的日期转换成Unix时间戳
     *
     * @param date 需要转换的日期 yyyy-MM-dd HH:mm:ss
     * @return long 时间戳
     * @author 冯赵杨
     * @date 2017年6月23日 上午10:38:13
     */
    public static long dateToUnixTimestamp(String date) {
        long timestamp = 0;
        try {
            timestamp = new SimpleDateFormat(DATE_FULL_STR).parse(date).getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return timestamp;
    }

    /**
     * 将指定的日期转换成Unix时间戳
     *
     * @param date 需要转换的日期 yyyy-MM-dd
     * @return long 时间戳
     * @author 冯赵杨
     * @date 2017年6月23日 上午10:38:13
     */
    public static long dateToUnixTimestamp(String date, String dateFormat) {
        long timestamp = 0;
        try {
            timestamp = new SimpleDateFormat(dateFormat).parse(date).getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return timestamp;
    }


    /**
     * 将Unix时间戳转换成日期
     *
     * @param timestamp 时间戳
     * @return String 日期字符串
     * @author 冯赵杨
     * @date 2017年6月23日 上午10:38:13
     */
    public static String unixTimestampToDate(long timestamp) {
        SimpleDateFormat sd = new SimpleDateFormat(DATE_FULL_STR);
        sd.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        return sd.format(new Date(timestamp));
    }

    /**
     * 获取传入时间之后的时间 单位：小时
     *
     * @param currentDate
     * @param after       当前时间之前(或者之后)的“小时”
     * @param type        当前时间之前为1，当前时间之后为2
     * @return
     * @author 冯赵杨
     * @date 2017年6月23日 上午10:38:13
     */
    public static Date getAfterHourDate(Date currentDate, int after, int type) {
        Calendar c = Calendar.getInstance();
        c.setTime(currentDate);
        if (type == 1) {
            c.set(Calendar.HOUR, c.get(Calendar.HOUR) - after);
        } else if (type == 2) {
            c.set(Calendar.HOUR, c.get(Calendar.HOUR) + after);
        }

        return c.getTime();
    }

    public static Date getAfterMinuteDate(Date currentDate, int after, int type) {
        Calendar c = Calendar.getInstance();
        c.setTime(currentDate);
        if (type == 1) {
            c.set(Calendar.MINUTE, c.get(Calendar.MINUTE) - after);
        } else if (type == 2) {
            c.set(Calendar.MINUTE, c.get(Calendar.MINUTE) + after);
        }

        return c.getTime();
    }

    public static Date getFirstDayOfThisWeek() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    public static Date getFirstDayOfBeforeWeek() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.WEEK_OF_YEAR, calendar.get(Calendar.WEEK_OF_YEAR) - 1);
        calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek() + 1);
        return calendar.getTime();
    }

    /**
     * 判断时间是否在时间段内
     *
     * @param strDate      当前时间 yyyy-MM-dd HH:mm:ss
     * @param strDateBegin 开始时间 00:00:00
     * @param strDateEnd   结束时间 00:05:00
     * @return
     * @author 冯赵杨
     * @date 2016年12月20日 下午5:34:25
     */
    public static boolean isInDate(String strDate, String strDateBegin, String strDateEnd) {
        // 截取当前时间时分秒
        int strDateH = Integer.parseInt(strDate.substring(11, 13));
        // int strDateM = Integer.parseInt(strDate.substring(14, 16));
        // int strDateS = Integer.parseInt(strDate.substring(17, 19));
        // 截取开始时间时分秒
        int strDateBeginH = Integer.parseInt(strDateBegin.substring(0, 2));
        // int strDateBeginM = Integer.parseInt(strDateBegin.substring(3, 5));
        // int strDateBeginS = Integer.parseInt(strDateBegin.substring(6, 8));
        // 截取结束时间时分秒
        int strDateEndH = Integer.parseInt(strDateEnd.substring(0, 2));
        // int strDateEndM = Integer.parseInt(strDateEnd.substring(3, 5));
        // int strDateEndS = Integer.parseInt(strDateEnd.substring(6, 8));

        // 当前时间小时数在开始时间和结束时间小时数之间
        return strDateH > strDateBeginH && strDateH < strDateEndH;
    }

    /**
     * 当前时间和pastDate比较返回毫秒数
     *
     * @param pastDate
     * @return
     * @author 冯赵杨
     * @date 2017年3月29日 下午5:20:48
     */
    public static Long getDiffTime(Date pastDate) {
        return System.currentTimeMillis() - pastDate.getTime();
    }

    /**
     * 校验字符串是否日期格式
     *
     * @param str
     * @param pattern
     * @return boolean
     * @author 冯赵杨
     * @date 2017年5月19日 上午9:55:33
     */
    public static boolean isValidDate(String str, String pattern) {
        DateFormat formatter = new SimpleDateFormat(pattern);
        try {
            Date date = formatter.parse(str);
            return str.equals(formatter.format(date));
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 获取当前日期的上月
     *
     * @author 冯赵杨
     * @date 2017年7月10日 下午4:46:53
     */
    public static String getLastMonth(Date nowDate) {
        Calendar c = Calendar.getInstance();
        c.setTime(nowDate);
        c.add(Calendar.MONTH, -1);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
        return format.format(c.getTime());
    }

    /**
     * 获取当前日期前range天的日期
     *
     * @param range 代表前几天的范围
     * @author 冯赵杨
     * @date 2017年2月10日 上午11:12:20
     */
    public static Date[] listCurrentDateBeforeDays(int range) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        Date[] dates = new Date[range];

        for (int i = 0; i < range; i++) {
            int beforeDay = -1;
            c.add(Calendar.DATE, beforeDay);
            Date date = c.getTime();
            String dateStr = sdf.format(date);
            date = sdf.parse(dateStr);
            dates[i] = date;
        }
        return dates;
    }

    public static long diffDays(Date startDate, Date endDate) {
        long nd = 1000 * 24 * 60 * 60;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - startDate.getTime();
        // 计算差多少天
        return diff / nd;
    }

    public static long diffHours(Date startDate, Date endDate) {
        long nh = 1000 * 60 * 60;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - startDate.getTime();
        // 计算差多少小时
        return diff / nh;
    }

    public static long diffMins(Date startDate, Date endDate) {
        long nm = 1000 * 60;
        // long ns = 1000;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - startDate.getTime();
        // 计算差多少分钟
        return diff / nm;
    }

    /**
     * 检查日期格式化格式是否合法
     *
     * @author 冯赵杨
     * @date 2018年3月8日 上午11:49:49
     */
    public static boolean checkDateFormat(String pattern) {
        return DATE_JFP_STR.equals(pattern) || DATE_FULL_STR.equals(pattern) || DATE_SMALL_STR.equals(pattern)
                || DATE_KEY_STR.equals(pattern) || DATE_ALL_STR.equals(pattern);
    }

}